package com.tbit.uqbike.webmanager.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.tbit.common.entity.view.Result;
import com.tbit.common.utils.TraceUtil;
import com.tbit.uqbike.manager.exception.BaseException;
import com.tbit.uqbike.object.business.Point;
import com.tbit.uqbike.object.pojo.*;
import com.tbit.uqbike.object.pojo.statistics.GramData;
import com.tbit.uqbike.object.pojo.vo.StatOrderByParkVO;
import com.tbit.uqbike.object.value.LoginInfo;
import com.tbit.uqbike.object.view.JsonResult;
import com.tbit.uqbike.object.view.NameObject;
import com.tbit.uqbike.object.view.OrderStatData;
import com.tbit.uqbike.quartz.SundryDataQuartz;
import com.tbit.uqbike.service.base.CalibrateService;
import com.tbit.uqbike.service.base.GeoService;
import com.tbit.uqbike.service.base.ParkPointService;
import com.tbit.uqbike.service.base.RedisService;
import com.tbit.uqbike.service.business.*;
import com.tbit.uqbike.service.rpcservice.StatService;
import com.tbit.uqbike.webmanager.util.*;
import com.tbit.uqbike.webmanager.util.excel.ExcelUtil;
import com.tbit.uqbike.webmanager.util.excel.ExportExcelUtil;
import com.tbit.uqbike.webmanager.util.excel.ExportExcelWrapper;
import com.tbit.utils.DateTimeUtil;
import com.tbit.utils.DoubleUtils;
import com.tbit.utils.Excel;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.RequestContext;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author MyWin E-mail:335918956@qq.com
 * @version 1.0
 * @createTime 2019-12-17 15:54
 */
@Slf4j
@Validated
@RestController
@RequestMapping(value = "/stat", produces = BaseController.MEDIA_JSON_UTF8)
public class StatController extends BaseController {

    @Autowired
    private StatService statService;
    @Autowired
    private RideLogService rideLogService;
    @Autowired
    private ParkPointService parkPointService;
    @Autowired
    private CalibrateService calibrateService;
    @Autowired
    private GeoService geoService;
    @Autowired
    private MemberFeeService memberFeeService;
    @Autowired
    private RideCardService rideCardService;
    @Autowired
    private VipCardService vipCardService;
    @Autowired
    private UserMealLogService userMealLogService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private SundryDataQuartz sundryDataQuartz;
    @Autowired
    private AccountSumStatService accountSumStatService;


    @RequestMapping("/statCarStatus")
    public JsonResult statCarStatus(@NotNull(message = "ver.accountIds.notNull") String accountIds, HttpServletRequest request) {
        LoginInfo li = getLogin(request);
        List<Integer> idList = StringUtil.getIntegerList(accountIds);
//        List<NameObject> data = statService.statCarStatusV2(li, idList);
        List<NameObject> data = statService.statCarStatusV3(li, idList);
        return JsonResult.ok(data);
    }

    @RequestMapping("/statTotalData")
    public JsonResult statTotalData(@NotNull(message = "ver.accountIds.notNull") String accountIds, Long startDt, Long endDt, Integer machineType, HttpServletRequest request) {
        LoginInfo li = getLogin(request);
        if (StrUtil.isBlank(accountIds)){
            return JsonResult.fail("请选择区域", TraceUtil.getTraceIdByLocal());
        }
        List<Integer> idList = StringUtil.getIntegerList(accountIds);
        if (idList.size() == 1 && idList.contains(-1)){
            return JsonResult.fail("请选择正确的区域", TraceUtil.getTraceIdByLocal());
        }
        Map<String, Object> data = statService.statTotalDatas(li, idList, machineType, startDt, endDt);
        return JsonResult.ok(data);
    }


    @RequestMapping("/statCurrentData")
    public JsonResult statCurrentData(@NotNull(message = "ver.accountIds.notNull") String accountIds, HttpServletRequest request) {
        LoginInfo li = getLogin(request);
        List<Integer> idList = StringUtil.getIntegerList(accountIds);
        Map<String, Object> data = statService.statCurrentData(li, idList);
        return JsonResult.ok(data);
    }


    /* 导出统计数据*/
    @RequestMapping(value = "/exportTotalData", produces = MEDIA_OCTET)
    public ResponseEntity exportMachineInfoTemplate(@NotNull(message = "ver.accountIds.notNull") String accountIds,
                                                    Long startDt, Long endDt, HttpServletRequest request) {
        // 下载模板文件
        LoginInfo info = getLogin(request);
        List<Integer> idList = StringUtil.getIntegerList(accountIds);
        List<OrderStatData> dataList = statService.statTotalByArea(info, idList, startDt, endDt);
        // 格式化数据:1、所有的数据全量写入；2、空一行打印统计；3、空两行打印押金和充值
        if (!dataList.isEmpty()) {
            dataList.add(null);
            dataList.add(OrderStatData.getTotalItem(dataList));
            dataList.add(null);
            dataList.add(null);
            OrderStatData first = dataList.get(0);
            if (first.totalDepositMoney != null) {
                OrderStatData destItem = new OrderStatData();
                destItem.name = "总押金";
                destItem.totalMoney = first.totalDepositMoney;
                destItem.totalOrder = first.totalDepositOrder;
                dataList.add(destItem);
            }
            if (first.totalRechargeMoney != null) {
                OrderStatData rechargeItem = new OrderStatData();
                rechargeItem.name = "总充值";
                rechargeItem.totalMoney = first.totalRechargeMoney;
                rechargeItem.totalOrder = first.totalRechargeOrder;
                dataList.add(rechargeItem);
            }
        }
        List<ExportExcelUtils.RowData> listContent = new LinkedList<>();
        for (OrderStatData item : dataList) {
            listContent.add(item);
        }
        byte[] data = ExportExcelUtils.exportExcelDataV2(OrderStatData.TOTAL_COLS, listContent);
        HttpHeaders headers = new HttpHeaders();

        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", "total.xls");

        return new ResponseEntity<>(data, headers, HttpStatus.OK);
    }

    @RequestMapping("/statCarBattery")
    public JsonResult statCarBattery(@NotNull(message = "ver.accountIds.notNull") String accountIds, HttpServletRequest request) {
        LoginInfo li = getLogin(request);
        List<Integer> idList = StringUtil.getIntegerList(accountIds);
        List<NameObject> data = statService.statCarBattery(li, idList);
        return JsonResult.ok(data);
    }

    @RequestMapping("/statCarIdle")
    public JsonResult statCarIdle(@NotNull(message = "ver.accountIds.notNull") String accountIds, HttpServletRequest request) {
        LoginInfo li = getLogin(request);
        List<Integer> idList = StringUtil.getIntegerList(accountIds);
        List<NameObject> data = statService.statCarIdle(li, idList);
        return JsonResult.ok(data);
    }

    /**
     * 用户数据看板-用户统计 (新的)
     *
     * @param accountIds
     * @param request
     * @return
     */
    @RequestMapping("/statNewUserNew")
    public JsonResult statNewUserNew(@NotNull(message = "ver.accountIds.notNull") String accountIds, HttpServletRequest request, Integer brandId) {
        /**获取传入的accountId,并拆分为集合*/
        List<Integer> idList = StringUtil.getIntegerList(accountIds);
        //统计用户数据
        List<NameObject> statUserData = accountSumStatService.statUserData(idList, brandId);
        return JsonResult.ok(statUserData);
    }


    @RequestMapping("/statNewUser")
    public JsonResult statNewUser(@NotNull(message = "ver.accountIds.notNull") String accountIds, HttpServletRequest request) {
        LoginInfo li = getLogin(request);
        List<Integer> idList = StringUtil.getIntegerList(accountIds);
        List<NameObject> data = statService.statNewUser(li, idList);
        /**该项是所有押金用户，实名用户，区域用户的总和*/
        Integer total = 0;
        for (NameObject item : data) {
            Integer v = new Long((Long) item.getValue()).intValue();
            if (v instanceof Integer) {
                total += v;
            }
        }
        NameObject no = new NameObject(UserStatInfo.PRO_TOTAL, total);
        data.add(no);
        return JsonResult.ok(data);
    }

    /**
     * 站点统计
     */
    @RequestMapping("/statByPark")
    public JsonResult statByStartPark(@NotNull(message = "ver.areaId.notNull") Integer accountId, @NotNull(message = "ver.startTime.notNull") Long startTime,
                                      @NotNull(message = "ver.endTime.notNull") Long endTime, Integer type, @RequestParam(defaultValue = "10") Integer rowCount,
                                      @RequestParam(defaultValue = "1") Integer pageNO, @RequestParam(required = false, value = "regionIds") String regionIds, @RequestParam(required = false, value = "changeType") Integer changeType) {
        List<Integer> regionIdList = StringUtil.getIntegerList(regionIds);
        List<StatPark> list = rideLogService.statByPark(accountId, type, startTime, endTime, pageNO, rowCount, regionIdList, changeType);
        Integer total = rideLogService.statByParkCount(accountId, type, startTime, endTime, regionIdList, changeType);
        return JsonResult.ok(list, total);
    }


    /**
     * 站点统计导出
     */
    @RequestMapping("/statExportByStartPark")
    public void statExportByStartPark(@NotNull(message = "ver.areaId.notNull") Integer accountId, @NotNull(message = "ver.startTime.notNull") Long startTime,
                                      @NotNull(message = "ver.endTime.notNull") Long endTime, Integer type,
                                      @RequestParam(required = false, value = "regionIds") String regionIds, HttpServletResponse response, @RequestParam(required = false, value = "changeType") Integer changeType) {
        try {
            List<Integer> regionIdList = StringUtil.getIntegerList(regionIds);
            List<StatPark> list = rideLogService.statByPark(accountId, type, startTime, endTime, null, null, regionIdList, changeType);
            List<String> cellNameList = new ArrayList<>();
            int row = 1;
            String fileName = "站点统计记录.xls";
            String title = "站点统计记录";
            HSSFWorkbook excel = null;
            String name = "借出数量";
            if (type == 1) {
                name = "归还数量";
            }
            if (changeType == 0) {
                cellNameList.add("站点名称");
                cellNameList.add(name);
                cellNameList.add("总金额(元)");
                excel = Excel.createExcel(title, cellNameList);
                for (StatPark statPark : list) {
                    List<String> excelData = new ArrayList<>();
                    excelData.add(statPark.getName() + "");
                    excelData.add(statPark.getTotal() + "");
                    excelData.add(DoubleUtils.toFloat(statPark.getMoney(), 100) + "");
                    excel = Excel.createExcelData(excel, excelData, row);
                    row++;
                }
            } else if (changeType == 1) {
                cellNameList.add("分区名称");
                cellNameList.add(name);
                cellNameList.add("总金额(元)");
                excel = Excel.createExcel(title, cellNameList);
                for (StatPark statPark : list) {
                    List<String> excelData = new ArrayList<>();
                    excelData.add(statPark.getRegionName() + "");
                    excelData.add(statPark.getTotal() + "");
                    excelData.add(DoubleUtils.toFloat(statPark.getMoney(), 100) + "");
                    excel = Excel.createExcelData(excel, excelData, row);
                    row++;
                }
            }
            OutputStream out = null;
            String headStr = "attachment; filename=\"" + new String(fileName.getBytes("utf-8"), "ISO8859-1") + "\"";
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", headStr);
            out = response.getOutputStream();
            excel.write(out);
            out.flush();
            out.close();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        List<Integer> regionIdList = StringUtil.getIntegerList(regionIds);
        List<StatPark> list = rideLogService.statByPark(accountId, type, startTime, endTime, null, null, regionIdList, changeType);
    }


    @RequestMapping("/statOrderByPark")
    public JsonResult statOrderByPark(@NotNull(message = "ver.areaId.notNull") Integer accountId, String name, String orderNO, Integer userCode, String phone, Integer type, @NotNull(message = "ver.startTime.notNull") Long startTime,
                                      @NotNull(message = "ver.endTime.notNull") Long endTime) {
        startPage();
        List<Map<String, Object>> list = rideLogService.statOrderByPark(new HashMap<>(8), accountId, name, orderNO, userCode, phone, type, startTime, endTime);
        return JsonResult.ok(list, (int) new PageInfo<>(list).getTotal());
    }


    /**
     * 导出站点订单统计
     * @return filename
     */
    @PostMapping("/exportStatOrderByPark")
    public Result<Object> exportStatOrderByPark(@NotNull(message = "ver.areaId.notNull") Integer accountId, @NotNull(message = "ver.startTime.notNull") Long startTime,
                                                  @NotNull(message = "ver.endTime.notNull") Long endTime, String name, String orderNO, Integer userCode, String phone, Integer type) {
        List<Map<String, Object>> list = rideLogService.statOrderByPark(new HashMap<>(8), accountId, name, orderNO, userCode, phone, type, startTime, endTime);
        List<StatOrderByParkVO> voList = new ArrayList<>();
        for (Map<String, Object> map : list) {
            StatOrderByParkVO parkVO = BeanUtil.toBean(map, StatOrderByParkVO.class);
            parkVO.setMoneyYuan(NumberUtil.div(parkVO.getMoney().intValue(), 100, 2));
            voList.add(parkVO);
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String fileName = String.format("%s~%s 站点订单统计", sdf.format(new Date(startTime)), sdf.format(new Date(endTime)));
        ExcelUtil<StatOrderByParkVO> excelUtil = new ExcelUtil<>(StatOrderByParkVO.class);
        JsonResult result = excelUtil.exportExcel(voList, fileName);
        return Result.success(result.getData());
    }





    /**
     * 站点热力图统计
     */
    @RequestMapping("/statHeatMap")
    public JsonResult statHeatMap(@NotNull(message = "ver.areaId.notNull") Integer accountId, @NotNull(message = "ver.startTime.notNull") Long startTime,
                                  @NotNull(message = "ver.endTime.notNull") Long endTime, Integer type, @RequestParam(defaultValue = "2") Integer mapType, HttpServletRequest request, @RequestParam(required = false, value = "regionIds") String regionIds) {

        List<HeatMapStat> list = parkPointService.statByPark(accountId, type, startTime, endTime, regionIds);
        Geo geo = geoService.getByAccountId(accountId);

        if (list.size() > 0) {
            /**经纬度校准*/
            for (HeatMapStat heat : list) {
                Point point = calibrateService.calibrateOffSet(heat.getLng(), heat.getLat(), mapType);
                heat.setLng(point.getX());
                heat.setLat(point.getY());
            }

        }
        if (geo != null) {
            HeatMapStat heatMapStat = new HeatMapStat();
            Point point = calibrateService.calibrateOffSet(geo.getCenterLo(), geo.getCenterLa(), mapType);
            heatMapStat.setCount(-1);
            heatMapStat.setLng(point.getX());
            heatMapStat.setLat(point.getY());
            list.add(0, heatMapStat);
        }

        return JsonResult.ok(list);
    }

    /**
     * 订单按天统计统计
     */
    @RequestMapping("/statRecharge")
    public JsonResult statRecharge(@NotNull(message = "ver.areaId.notNull") Integer accountId, @NotNull(message = "ver.startTime.notNull") Long startTime,
                                   @NotNull(message = "ver.endTime.notNull") Long endTime) {
        List<StatPark> list = rideLogService.statRecharge(accountId, startTime, endTime);
        return JsonResult.ok(list);
    }

    /**
     * 订单统计导出
     */
    @RequestMapping("/statExport")
    public void statExport(@NotNull(message = "ver.areaId.notNull") Integer accountId, @NotNull(message = "ver.startTime.notNull") Long startTime,
                           @NotNull(message = "ver.endTime.notNull") Long endTime, HttpServletResponse response, String regionIds, Integer type) {
        RequestContext context = getLogin(ServletUtils.getRequest()).context;
        List<Integer> regionList = StringUtil.getIntegerList(regionIds);
        List<String[]> exportList = new ArrayList<>();
        if (type == 0) {
            List<StatPark> list = rideLogService.statLineChart(accountId, startTime, endTime, regionIds, type, false);
            exportList.add(new String[]{context.getMessage("excel_head_ridelog_time"),"车辆总数", "投放车辆数", "产生订单车辆数", "订单总数(个)",  "订单收入总金额(元)",  "订单车辆率"});
            list.stream().forEach(lists -> {
                String[] str = new String[7];
                str[0] = String.valueOf(lists.getName());
                str[1] = String.valueOf(lists.getMachineNum());
                str[2] = String.valueOf(lists.getPutInMachineCount());
                str[3] = String.valueOf(lists.getHaveOrderCount());
                str[4] = String.valueOf(lists.getTotal());
                str[5] = String.valueOf(DoubleUtils.doubleScale(new Double(lists.getMoney().toString())) / 100.0);
                str[6] = lists.getPutInMachineCount() == 0 ? "0" :  NumberUtil.mul(NumberUtil.div(lists.getHaveOrderCount(), lists.getPutInMachineCount(), 2), 100) + "%";
                exportList.add(str);
            });
            ExportExcelWrapper<String[]> export = new ExportExcelWrapper<>();
            export.exportExcel(context.getMessage("excel_head_ridelog_export"), context.getMessage("excel_head_ridelog_export"), null, exportList, response, ExportExcelUtil.EXCEL_FILE_2003);
        }
        if (type == 1) {
            List<StatPark> list = rideLogService.statLineChart(accountId, startTime, endTime, regionIds, type, false);
            exportList.add(new String[]{context.getMessage("excel_head_ridelog_time"), context.getMessage("excel_head_site_regionName"), "车辆总数", "产生订单车辆数", context.getMessage("excel_head_ridelog_total"), context.getMessage("excel_head_ridelog_sum") });
            list.stream().forEach(lists -> {
                String[] str = new String[6];
                str[0] = String.valueOf(lists.getName());
                str[1] = String.valueOf(lists.getRegionName());
                str[2] = String.valueOf(lists.getMachineNum());
                str[3] = String.valueOf(lists.getHaveOrderCount());
                str[4] = String.valueOf(DoubleUtils.doubleScale(new Double(lists.getMoney().toString())) / 100.0);
                str[5] = String.valueOf(lists.getTotal());

                exportList.add(str);
            });
            ExportExcelWrapper<String[]> exports = new ExportExcelWrapper<>();
            exports.exportExcel(context.getMessage("excel_head_ridelog_export"), context.getMessage("excel_head_ridelog_export"), null, exportList, response, ExportExcelUtil.EXCEL_FILE_2003);
        }
    }

    /**
     * 站点统计数据
     */
    @RequestMapping("/statLineChart")
    public JsonResult statLineChart(@NotNull(message = "ver.areaId.notNull") Integer accountId, @NotNull(message = "ver.startTime.notNull") Long startTime,
                                    @NotNull(message = "ver.endTime.notNull") Long endTime, @RequestParam(required = false, value = "regionIds") String regionIds,
                                    @RequestParam(required = false, value = "type", defaultValue = "0") Integer type, @RequestParam(required = false, value = "picType") Integer picType) {
        List<StatPark> list = rideLogService.statLineChart(accountId, startTime, endTime, regionIds, type, false);

        return JsonResult.ok(list);
    }


    /**
     * 订单统计折线图数据
     */
    @RequestMapping("/statLineChartByPic")
    @ResponseBody
    public JsonResult statLineChartByPic(StatLineChartByPic statLineChartByPic, HttpServletRequest request) {
        List<StatPark> list = rideLogService.statLineChart(statLineChartByPic.getAccountId(), statLineChartByPic.getStartTime(), statLineChartByPic.getEndTime(), null, 1, true);

        List<StatPark> listTotal = rideLogService.statLineChart(statLineChartByPic.getAccountId(), statLineChartByPic.getStartTime(), statLineChartByPic.getEndTime(), null, 0, true);

        List<StatParkDTO> parkDTOList = new ArrayList<>();
        Map<Integer, List<StatPark>> map = new HashMap<>();
        for (StatPark statPark : list) {
            Integer regionId = statPark.getRegionId();
            List<StatPark> lstStatPark = null;
            if (map.containsKey(regionId)) {
                lstStatPark = map.get(regionId);
            } else {
                lstStatPark = new ArrayList<>();
            }
            lstStatPark.add(statPark);
            map.put(regionId, lstStatPark);
        }
        for (Map.Entry<Integer, List<StatPark>> entry : map.entrySet()) {
            StatParkDTO statParkDTO = new StatParkDTO();
            statParkDTO.setRegionId(entry.getValue().get(0).getRegionId());
            statParkDTO.setRegionName(entry.getValue().get(0).getRegionName());
            statParkDTO.setStatParkList(entry.getValue());
            parkDTOList.add(statParkDTO);
        }

        return JsonResult.ok(parkDTOList, listTotal);
    }


    /**
     * 通过类型查询区域总收入和总订单量
     */
    @RequestMapping("/statMoneyByType")
    public JsonResult statMoneyByType(@NotNull(message = "ver.accountIds.notNull") String accountIds, @NotNull(message = "ver.startTime.notNull") Long startTime,
                                      @NotNull(message = "ver.endTime.notNull") Long endTime, @RequestParam(defaultValue = "0") Integer type) {
        List<Integer> idList = StringUtil.getIntegerList(accountIds);
        List<NameObject> list = statService.statMoneyByType(idList, startTime, endTime, type);
        return JsonResult.ok(list);
    }

    /**
     * 订单按天统计或按月统计柱状图数据
     */
    @RequestMapping("/statMoByTime")
    public JsonResult statMoByTime(@NotNull(message = "ver.accountIds.notNull") String accountIds, @NotNull(message = "ver.startTime.notNull") Long startTime,
                                   @NotNull(message = "ver.endTime.notNull") Long endTime, @RequestParam(defaultValue = "0") Integer type, @RequestParam(defaultValue = "0") Integer selectType) {
        List<Integer> idList = StringUtil.getIntegerList(accountIds);
        List<GramData> list = statService.statMoByTime(idList, startTime, endTime, type, selectType);
        return JsonResult.ok(list);
    }

    /**
     * 用户数据看板-用户年龄分布
     */
    @RequestMapping("/groupByBirth")
    public JsonResult groupByBirth(@NotNull(message = "ver.accountIds.notNull") String accountIds) {
        List<Integer> idList = StringUtil.getIntegerList(accountIds);
        String redisCache = redisService.get(String.format("groupByBirthCache:%s", accountIds));
        if (StringUtils.isNotEmpty(redisCache)) {
            List<NameObject> nameObjects = JSON.parseArray(redisCache, NameObject.class);
            return JsonResult.ok(nameObjects);
        }
        List<NameObject> list = statService.groupByBirth(idList);
        redisService.add(String.format("groupByBirthCache:%s", accountIds), JSON.toJSONString(list), 7200);
        return JsonResult.ok(list);
    }

    /**
     * 用户数据看板-用户性别分布
     */
    @RequestMapping("/groupBySex")
    public JsonResult groupBySex(@NotNull(message = "ver.accountIds.notNull") String accountIds) {
        List<Integer> idList = StringUtil.getIntegerList(accountIds);
        String redisCache = redisService.get(String.format("groupBySexCache:%s", accountIds));
        if (StringUtils.isNotEmpty(redisCache)) {
            List<NameObject> nameObjects = JSON.parseArray(redisCache, NameObject.class);
            return JsonResult.ok(nameObjects);
        }
        List<NameObject> list = statService.groupBySex(idList);
        redisService.add(String.format("groupBySexCache:%s", accountIds), JSON.toJSONString(list), 7200);
        return JsonResult.ok(list);
    }

    /**
     * 用户数据看板-用户月、天增长统计
     */
    @RequestMapping("/statUserByType")
    public JsonResult statUserByType(@NotNull(message = "ver.accountIds.notNull") String accountIds, @NotNull(message = "ver.startTime.notNull") Long startTime,
                                     @NotNull(message = "ver.endTime.notNull") Long endTime, @RequestParam(defaultValue = "0") Integer type, @RequestParam(defaultValue = "0") Integer selectType) {
        List<Integer> idList = StringUtil.getIntegerList(accountIds);
        List<NameObject> list = statService.statUserByType(idList, startTime, endTime, type);
        return JsonResult.ok(list);
    }

    /**
     * 根据区域id获取今日新增用户
     *
     * @param accountIds 区域id,英文逗号拼接
     */
    @RequestMapping("/todayNewUser")
    public JsonResult todayNewUser(@NotNull(message = "ver.accountIds.notNull") String accountIds) {
        List<Integer> idList = StringUtil.getIntegerList(accountIds);
        return JsonResult.ok(statService.todayNewUser(idList));
    }

    /**
     * 平台用户总余额统计、总欠款统计、总数统计、押金用户总数统计、押金用户总金额统计、车辆总数统计
     */
    @RequestMapping("/statByBid")
    public JsonResult statByBid(@NotNull(message = "ver.accountId.notNull") Integer accountId) {
        JSONObject jsonObject = statService.statByBid(accountId);
        return JsonResult.ok(jsonObject.toJSONString());
    }

    /**
     * 骑行卡订单按天统计
     *
     * @param accountId
     * @param startTime
     * @param endTime
     * @return
     */
    @RequestMapping("/statRideCardByTime")
    public JsonResult statRideCardByTime(@NotNull(message = "ver.areaId.notNull") Integer accountId, @NotNull(message = "ver.startTime.notNull") Long startTime,
                                         @NotNull(message = "ver.endTime.notNull") Long endTime) {
        List<Integer> accountIds = new LinkedList<>();
        accountIds.add(accountId);
        List<StatPark> rideStat = rideCardService.statByType(accountIds,
                DateTimeUtil.DateTimeToString(new Date(startTime)), DateTimeUtil.DateTimeToString(new Date(endTime)), 0);
        return JsonResult.ok(rideStat);
    }

    /**
     * 免押卡订单按天统计
     *
     * @param accountId
     * @param startTime
     * @param endTime
     * @return
     */
    @RequestMapping("/statMemByTime")
    public JsonResult statMemByTime(@NotNull(message = "ver.areaId.notNull") Integer accountId, @NotNull(message = "ver.startTime.notNull") Long startTime,
                                    @NotNull(message = "ver.endTime.notNull") Long endTime) {
        List<Integer> accountIds = new LinkedList<>();
        accountIds.add(accountId);
        List<StatPark> rideStat = memberFeeService.statByType(accountIds,
                DateTimeUtil.DateTimeToString(new Date(startTime)), DateTimeUtil.DateTimeToString(new Date(endTime)), 0);
        return JsonResult.ok(rideStat);
    }

    /**
     * 会员卡按天统计订单订单量
     *
     * @param accountId
     * @param startTime
     * @param endTime
     * @return
     */
    @RequestMapping("/statVipByTime")
    public JsonResult statVipByTime(@NotNull(message = "ver.areaId.notNull") Integer accountId, @NotNull(message = "ver.startTime.notNull") Long startTime,
                                    @NotNull(message = "ver.endTime.notNull") Long endTime) {
        List<StatPark> rideStat = vipCardService.groupByDay(accountId, startTime, endTime);
        return JsonResult.ok(rideStat);
    }

    /**
     * @param accountId
     * @param startTime
     * @param endTime
     * @return com.tbit.uqbike.object.view.JsonResult
     * @Description: 骑行订单日统计
     * @createDate 2020/12/9 17:32
     */
    @PostMapping("/ridelogByDay")
    public JsonResult ridelogByDay(@NotNull(message = "ver.areaId.notNull") Integer accountId, @NotNull(message = "ver.startTime.notNull") Long startTime, @NotNull(message = "ver.endTime.notNull") Long endTime) {
        List<Map<String, Object>> result = rideLogService.ridelogByDay(accountId, startTime, endTime, null);
        return JsonResult.ok(result);
    }

    /**
     * @param accountId
     * @param startTime
     * @param endTime
     * @param response
     * @return com.tbit.uqbike.object.view.JsonResult
     * @Description: 骑行订单日统计导出
     * @createDate 2020/12/9 17:32
     */
    @GetMapping("/exportrRidelogByDay")
    public void exportrRidelogByDay(@NotNull(message = "ver.areaId.notNull") Integer accountId, @NotNull(message = "ver.startTime.notNull") Long startTime, @NotNull(message = "ver.endTime.notNull") Long endTime, HttpServletResponse response) {
        RequestContext context = getLogin(ServletUtils.getRequest()).getContext();
        List<Map<String, Object>> result = rideLogService.ridelogByDay(accountId, startTime, endTime, null);
        List<String[]> exportList = new ArrayList<>();
        exportList.add(new String[]{context.getMessage("excel_head_ridelog_time"), context.getMessage("excel_head_ridelog_total"), context.getMessage("excel_head_ridelog_sum")});
        result.stream().forEach(res -> {
            String[] str = new String[3];
            str[0] = String.valueOf(res.get("time"));
            str[1] = String.valueOf(DoubleUtils.doubleScale(new Double(res.get("money").toString())) / 100.0);
            str[2] = String.valueOf(res.get("num"));
            exportList.add(str);
        });
        ExportExcelWrapper<String[]> export = new ExportExcelWrapper<>();
        export.exportExcel(context.getMessage("excel_head_ridelog_export"), context.getMessage("excel_head_ridelog_export"), null, exportList, response, ExportExcelUtil.EXCEL_FILE_2003);
    }


    /**
     * 骑行卡订单按天统计导出
     *
     * @param accountId
     * @param startTime
     * @param endTime
     * @return
     */
    @RequestMapping("/exportRideCardByTime")
    public void exportRideCardByTime(@NotNull(message = "ver.areaId.notNull") Integer accountId, @NotNull(message = "ver.startTime.notNull") Long startTime,
                                     @NotNull(message = "ver.endTime.notNull") Long endTime, HttpServletResponse response) {
        RequestContext context = getLogin(ServletUtils.getRequest()).context;
        List<Integer> accountIds = new LinkedList<>();
        accountIds.add(accountId);
        List<StatPark> rideStat = rideCardService.statByType(accountIds,
                DateTimeUtil.DateTimeToString(new Date(startTime)), DateTimeUtil.DateTimeToString(new Date(endTime)), 0);
        List<String[]> exportList = RechargeExportUtil.getExportContent(rideStat, context);
        ExportExcelWrapper<String[]> export = new ExportExcelWrapper<>();
        export.exportExcel(context.getMessage("excel_head_ridecard_export"), context.getMessage("excel_head_ridecard_export"), null, exportList, response, ExportExcelUtil.EXCEL_FILE_2003);
//            ExportExcelUtils.exportExcel(response, "骑行卡订单统计", stringList);
    }

    /**
     * 免押卡订单按天统计导出
     *
     * @param accountId
     * @param startTime
     * @param endTime
     * @return
     */
    @RequestMapping("/exportMemByTime")
    public void exportMemByTime(@NotNull(message = "ver.areaId.notNull") Integer accountId, @NotNull(message = "ver.startTime.notNull") Long startTime,
                                @NotNull(message = "ver.endTime.notNull") Long endTime, HttpServletResponse response) {
        RequestContext context = getLogin(ServletUtils.getRequest()).context;
        List<Integer> accountIds = new LinkedList<>();
        accountIds.add(accountId);
        List<StatPark> memStat = memberFeeService.statByType(accountIds,
                DateTimeUtil.DateTimeToString(new Date(startTime)), DateTimeUtil.DateTimeToString(new Date(endTime)), 0);
        List<String[]> exportList = RechargeExportUtil.getExportContent(memStat, context);
        ExportExcelWrapper<String[]> export = new ExportExcelWrapper<>();
        export.exportExcel(context.getMessage("excel_head_membercard_export"), context.getMessage("excel_head_membercard_export"), null, exportList, response, ExportExcelUtil.EXCEL_FILE_2003);
//            ExportExcelUtils.exportExcel(response, "免押卡订单统计", stringList);

    }

    /**
     * 会员卡按天统计订单订单导出
     *
     * @param accountId
     * @param startTime
     * @param endTime
     * @return
     */
    @RequestMapping("/exportVipByTime")
    public void exportVipByTime(@NotNull(message = "ver.areaId.notNull") Integer accountId, @NotNull(message = "ver.startTime.notNull") Long startTime,
                                @NotNull(message = "ver.endTime.notNull") Long endTime, HttpServletResponse response) {
        RequestContext context = getLogin(ServletUtils.getRequest()).context;
        List<StatPark> vipStat = vipCardService.groupByDay(accountId, startTime, endTime);
        List<String[]> exportList = RechargeExportUtil.getExportContent(vipStat, context);
        ExportExcelWrapper<String[]> export = new ExportExcelWrapper<>();
        export.exportExcel(context.getMessage("excel_head_vipcard_export"), context.getMessage("excel_head_vipcard_export"), null, exportList, response, ExportExcelUtil.EXCEL_FILE_2003);
//            ExportExcelUtils.exportExcel(response, "会员卡订单统计", stringList);
    }

    /**
     * 查询用户购买套餐日志列表
     */
    @GetMapping("/list")
    public JsonResult list(UserMealLog userMealLog) {
        Assert.notNull(userMealLog.getAccountId(), "ver.areaId.notNull");
        Map<String, Object> map = new HashMap<>();
        map.put("beginTime", userMealLog.getStartTime());
        map.put("endTime", userMealLog.getEndTime());
        userMealLog.setParams(map);
        int money = userMealLogService.selectCount(userMealLog);
        startPage();
        List<UserMealLog> list = userMealLogService.selectUserMealLogList(userMealLog);
        int total = (int) new PageInfo<>(list).getTotal();
        return JsonResult.ok(list, total, money, total);
    }

    /**
     * 导出用户购买套餐日志列表
     */
    @GetMapping("/export")
    public JsonResult export(UserMealLog userMealLog) {
        Assert.notNull(userMealLog.getAccountId(), "ver.areaId.notNull");
        Map<String, Object> map = new HashMap<>();
        map.put("beginTime", userMealLog.getStartTime());
        map.put("endTime", userMealLog.getEndTime());
        userMealLog.setParams(map);
        List<UserMealLog> list = userMealLogService.selectUserMealLogList(userMealLog);
        list.forEach(UserMealLog::unitConversion);
        ExcelUtil<UserMealLog> util = new ExcelUtil<UserMealLog>(UserMealLog.class);
        return util.exportExcel(list, "优惠券套餐");
    }

    /**
     * 套餐按天统计
     */
    @GetMapping("/time")
    public JsonResult time(UserMealLog userMealLog) {
        Assert.notNull(userMealLog.getAccountId(), "ver.areaId.notNull");
        Map<String, Object> map = new HashMap<>();
        map.put("beginTime", userMealLog.getStartTime());
        map.put("endTime", userMealLog.getEndTime());
        userMealLog.setParams(map);
        List<StatPark> result = userMealLogService.selectByTime(userMealLog);
        return JsonResult.ok(result);
    }

    /**
     * 套餐按天统计导出
     */
    @GetMapping("/exportTime")
    public JsonResult exportTime(UserMealLog userMealLog) {
        Assert.notNull(userMealLog.getAccountId(), "ver.areaId.notNull");
        Map<String, Object> map = new HashMap<>();
        map.put("beginTime", userMealLog.getBeginTime());
        map.put("endTime", userMealLog.getEndTime());
        userMealLog.setParams(map);
        List<StatPark> result = userMealLogService.selectByTime(userMealLog);
        List<UserMealLogByDayExportVO> list = new LinkedList<>();
        for (StatPark statPark : result) {
            //导出数据处理
            UserMealLogByDayExportVO userMealLogByDayExportVO = new UserMealLogByDayExportVO();
            BeanUtils.copyProperties(statPark, userMealLogByDayExportVO);
            userMealLogByDayExportVO.excelDataDeal();
            list.add(userMealLogByDayExportVO);
        }
        ExcelUtil<UserMealLogByDayExportVO> util = new ExcelUtil<>(UserMealLogByDayExportVO.class);
        return util.exportExcel(list, "优惠券套餐");
    }


    /**
     * 提供给运维端获取罚款费用
     * @param map accountIds 区域id集合 startDt 开始时间 endDt 结束时间
     * @return result
     */
    @GetMapping("/getFineMoney")
    public Result<Object> getFineMoney(@RequestBody Map<String, Object> map) {
        boolean result = MD5PasswordUtil.signCheck(map.get("sign").toString(), Long.parseLong(map.get("date").toString()), map.get("param").toString());
        if (!result) {
            throw new BaseException("签名校验失败");
        }
        return statService.getFineMoney(map);
    }

    /**
     * 产生订单数车辆折线图
     * @param statLineChartByPic statLineChartByPic
     * @return result
     */
    @PostMapping("/hasOrder")
    public JsonResult hasOrder(@RequestBody StatLineChartByPic statLineChartByPic){
        return statService.hasOrder(statLineChartByPic);
    }

}
